#ifndef GUI_DOCUMENT_H
#define GUI_DOCUMENT_H

#include "MDIView.h"
#include "persistence.h"
#include "App/Document.h"
class Gui_Application;
namespace App
{
	class Document;
	class DocumentObject;
	class ViewProviderDocumentObject;
}
namespace Gui {

	class ViewProvider;
	class ViewProviderDocumentObject;
	//class Application;

class Gui_Document :  public Base::Persistence
{
public:
	Gui_Document(App::Document* pcDocument, Gui_Application * app);
	~Gui_Document(void);

public:

	void createView(const char* sType); 
	//bool save(void);
	void clearScene();
    App::Document*  getDocument(void) const;


	void attachView(Gui::BaseView* pcView, bool bPassiv=false);
	/// Detach a view (get called by the MDIView destructor)
	void detachView(Gui::BaseView* pcView, bool bPassiv=false);
protected:

	void slotNewObject(const App::DocumentObject&);
	void slotDeletedObject(const App::DocumentObject&);
	void slotChangedObject(const App::DocumentObject&, const App::Property&);
	void slotRenamedObject(const App::DocumentObject&);
	void slotActivatedObject(const App::DocumentObject&);
	void slotRestoredDocument(const App::Document&);

public:
	/** @name Signals of the document */
	//@{
	/// signal on new Object
	mutable boost::signal<void (const Gui::ViewProviderDocumentObject&)> signalNewObject;
	/// signal on deleted Object
	mutable boost::signal<void (const Gui::ViewProviderDocumentObject&)> signalDeletedObject;
	/// signal on changed Object, the 2nd argument is the changed property
	/// of the referenced document object, not of the view provider
	mutable boost::signal<void (const Gui::ViewProviderDocumentObject&,
		const App::Property&)> signalChangedObject;
	/// signal on renamed Object
	mutable boost::signal<void (const Gui::ViewProviderDocumentObject&)> signalRenamedObject;
	/// signal on activated Object
	mutable boost::signal<void (const Gui::ViewProviderDocumentObject&)> signalActivatedObject;
	/// signal on goes in edti mode
	mutable boost::signal<void (const Gui::ViewProviderDocumentObject&)> signalInEdit;
	/// signal on leave edit mode
	mutable boost::signal<void (const Gui::ViewProviderDocumentObject&)> signalResetEdit;
	
	/// Save the document
	bool save(void);
	/// Save the document under a new file name
	bool saveAs(void);
	/// This method is used to save properties or very small amounts of data to an XML document.
	virtual void Save (Base::Writer &writer) const;
	/// This method is used to restore properties from an XML document.
	virtual void Restore(Base::XMLReader &reader);
	/// This method is used to save large amounts of data to a binary file.
	virtual void SaveDocFile (Base::Writer &writer) const;
	/// This method is used to restore large amounts of data from a binary file.
	virtual void RestoreDocFile(Base::Reader &reader);

    ViewProvider *getViewProviderByName(const char* name) const;

	void setModified(bool);
	bool isModified() const;
	void onUpdate(void);

	//////////////////////////////////////////////////////////////////////////

	/// handels the application close event
	bool canClose();
	bool isLastView(void);


	//////////////////////////////////////////////////////////////////////////

	  ViewProvider* getViewProvider(const App::DocumentObject *) const;

	  void updataDocumentObjectMaterial(const App::DocumentObject*);


	 std::list<MDIView*> getMDIViews() const;
     MDIView* getActiveView(void) const;
	 unsigned int getMemSize (void) const;

	 ////////////////// [3/20/2012 Administrator]
	 bool setEdit(Gui::ViewProvider* p, int ModNum=0);
	 /// reset from edit mode
	 void resetEdit(void);

	 ViewProvider *getInEdit(void) const;

	 //////////////////////////////////////////////////////////////////////////
	 Gui::ViewProvider* _getObject(const char* name);

	


private:
	struct DocumentP* d;
	static int _iDocCount;

	/// undo names list
	std::list<std::string> listUndoNames;
	/// redo names list
	std::list<std::string> listRedoNames;

};

}

#endif